package com.suse.warmstill.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.suse.warmstill.common.enums.ResponseEnum;
import com.suse.warmstill.common.exception.BusinessException;
import com.suse.warmstill.common.model.CallResult;
import com.suse.warmstill.entity.TbMenu;
import com.suse.warmstill.entity.TbRoleMenu;
import com.suse.warmstill.mapper.TbMenuMapper;
import com.suse.warmstill.service.BaseService;
import com.suse.warmstill.service.MenuService;
import com.suse.warmstill.service.RoleMenuService;
import com.suse.warmstill.transaction.TransactionService;
import com.suse.warmstill.vo.ConditionVO;
import com.suse.warmstill.vo.MenuOption;
import com.suse.warmstill.vo.MenuVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author 黄靖
 * @author 2022-10-20 17:16
 * description:
 **/
@Service
public class MenuServiceImpl implements MenuService, BaseService<MenuVo, TbMenu> {
    @Autowired
    private TbMenuMapper menuMapper;

    @Autowired
    private RoleMenuService roleMenuService;

    @Autowired
    private TransactionService transactionService;


    @Override
    public Page<TbMenu> listMenus(ConditionVO conditionVO) {
        final LambdaQueryWrapper<TbMenu> tbMenuLambdaQueryWrapper = new LambdaQueryWrapper<>();

        if (StringUtils.isNotBlank(conditionVO.getKeyword())) {
            tbMenuLambdaQueryWrapper.like(TbMenu::getName, conditionVO.getKeyword());
        }
        tbMenuLambdaQueryWrapper.eq(TbMenu::getParentId, 0);
        final Page<TbMenu> tbMenuPage = new Page<>(conditionVO.getCurrent(), conditionVO.getSize());
        final Page<TbMenu> tbMenuPage1 = menuMapper.selectPage(tbMenuPage, tbMenuLambdaQueryWrapper);


        return tbMenuPage1;
    }


    @Override
    public TbMenu toEntity(MenuVo vo) {
        final TbMenu tbMenu = new TbMenu();
        tbMenu.setId(vo.getId());
        tbMenu.setIsHidden(vo.getIsHidden());
        tbMenu.setName(vo.getName());
        tbMenu.setPath(vo.getPath());
        tbMenu.setParentId(vo.getParentId());
        tbMenu.setTitle(vo.getTitle());
        tbMenu.setRedirect(vo.getRedirect());
        return tbMenu;
    }

    @Override
    public MenuVo toVo(TbMenu entity) {
        final MenuVo menuVo = new MenuVo();
        menuVo.setId(entity.getId());
        menuVo.setIsHidden(entity.getIsHidden());
        menuVo.setParentId(entity.getParentId());
        menuVo.setRedirect(entity.getRedirect());
        menuVo.setTitle(entity.getTitle());
        menuVo.setPath(entity.getPath());
        menuVo.setName(entity.getName());


        return menuVo;
    }


    @Override
    public void inserOne(MenuVo menuVo) {
        if (ObjectUtils.isNotEmpty(menuMapper.selectOne(new LambdaQueryWrapper<TbMenu>().eq(TbMenu::getName, menuVo.getName())))) {
            throw new BusinessException(ResponseEnum.REPEAT_DATA.getCode(), ResponseEnum.REPEAT_DATA.getMsg());
        }

        final TbMenu tbMenu = toEntity(menuVo);
        tbMenu.setId(null);
        menuMapper.insert(tbMenu);
    }

    @Override
    public void update(MenuVo menuVo) {
        menuMapper.updateById(toEntity(menuVo));
    }

    @Override
    public void logicDeleteOne(Long id) {

        final LambdaQueryWrapper<TbMenu> tbMenuMapperLambdaQueryWrapper = new LambdaQueryWrapper<>();
        tbMenuMapperLambdaQueryWrapper.eq(TbMenu::getId, id);


        transactionService.process(() -> {
            menuMapper.delete(tbMenuMapperLambdaQueryWrapper);

            roleMenuService.deleteByMenuId(id);
        });


    }


    @Override
    public Set<MenuVo> getChildren(Long id) {

        final LambdaQueryWrapper<TbMenu> wrapper = new LambdaQueryWrapper<>();

        wrapper.eq(TbMenu::getParentId, id);

        final Set<MenuVo> collect = menuMapper.selectList(wrapper).stream().map(entity -> {
            return toVo(entity);
        }).collect(Collectors.toSet());


        return collect;
    }


    @Override
    public List<MenuOption> listMenuOption(ConditionVO conditionVO) {
        //1、先查出 父节点
        final Page<TbMenu> tbMenuPage = listMenus(conditionVO);
        final List<TbMenu> records = tbMenuPage.getRecords();

        final List<MenuOption> menuOptions = new ArrayList<>();
        for (TbMenu menu : records
        ) {
            final MenuOption menuOption = new MenuOption();
            menuOption.setTitle(menu.getTitle());
            menuOption.setId(menu.getId());
            menuOption.setParentId(Long.valueOf(menu.getParentId()));
            final List<MenuOption> children = findChildren(menu.getId());
            menuOption.setChildren(children);/*if(ObjectUtils.isNotEmpty(children)){

           }*/

            menuOptions.add(menuOption);

        }
        return menuOptions;
    }

    public List<MenuOption> findChildren(Long parentId) {

        final List<TbMenu> tbMenus = menuMapper.selectList(new LambdaQueryWrapper<TbMenu>().eq(TbMenu::getParentId, parentId));

        final List<MenuOption> menuOptions = new ArrayList<>();
        for (TbMenu menu : tbMenus
        ) {
            final MenuOption menuOption = new MenuOption();
            menuOption.setTitle(menu.getTitle());
            menuOption.setId(menu.getId());
            menuOption.setParentId(Long.valueOf(menu.getParentId()));
            menuOptions.add(menuOption);
        }
        return menuOptions;

    }

}
